/**
 * All the functions needed for player objects
 *
 * Originally written by: Jonas Strandstedt
 */


/**
 * initObject ainitialises the object
 * @param PlayerObject *obj = the object to be initialised
 * @param char filename[100] = the filename of the obj file
 * @param char name[20] = an identifier string or name
 * @param mass = the object mass
 */
void initPlayerObject(PlayerObject *obj, char filename[100], char name[20], float mass, float scale, XYZ rotation) {
	
	// printing to console and setting up name
	printf("Initializing %s\n",name);
	strcpy((*obj).identifier,name);
	(*obj).score = 0;
	(*obj).death = 0;
	(*obj).life = 100;
	
	(*obj).isDead = 1;
	
	(*obj).weapon = 0;
	(*obj).ammo = 0;
	(*obj).lastShootTime = 0.0;
	
	obj->mesh = (ObjectMesh*)malloc(sizeof(ObjectMesh));
	
	(*obj).angle.x = 0;
	(*obj).angle.y = 0;
	(*obj).angle.z = 0;	
	
	(*obj).angleRotation.x = 0.1;
	(*obj).angleRotation.y = 0.1;
	(*obj).angleRotation.z = 0.1;	
	
	(*obj).velocity.x = 0;	
	(*obj).velocity.y = 0;	
	(*obj).velocity.z = 0;
	
	(*obj).directionalVelocity = 0;
	
	(*obj).force = 0.9;		
	(*obj).mass = mass;		
	(*obj).maxVelocity = 1.0;
	
	(*obj).pos.x = 0.0; 
	(*obj).pos.y = 0.0; 
	(*obj).pos.z = 0.0;
	
	(*obj).effect = 0;
	(*obj).effect_timer = 0.0;
	
	(*obj).partsUsed = 0;
	
	initObjectMesh(obj->mesh,filename, scale,rotation);
	
	(*obj).cameraAngle = 0.0;
	
	printf("..Done!\n\n");
}

/**
 * allocatePartMemory allocates memory for the parts of the object
 * @param PlayerObject *obj
 * @param int number = the number of objects to allocate memory for
 */
void allocatePartMemory(PlayerObject *obj, int number) {
	printf("Allocating memory for %i parts for %s\n",number,obj->identifier);
	
	obj->parts = (StaticObject*)malloc(number*sizeof(StaticObject));
	int n = 0;
	while (n <= number) {
		StaticObject *temp = (obj->parts +n);
		temp->mesh = (ObjectMesh*)malloc(sizeof(ObjectMesh));
		n++;
	}
	printf("\n");
}

/**
 * addStaticObject adds a static object to the playerobject
 * @param PlayerObject *obj = the player to add an object to
 * @param Location pos = the position relative to the player
 * @param float angle = the angle relative to the player
 */
void addStaticObject(PlayerObject *obj, char filename[100], Location pos, float angle, float scale, XYZ rotation) {
	
	printf("Mounting part to %s at (x,y,z)=(%.3f,%.3f,%.3f) angle=%.2f\n",obj->identifier,pos.x,pos.y,pos.z,angle);
	
	int partsUsed = obj->partsUsed;
	StaticObject *temp = (obj->parts + partsUsed);
	initStaticObject(temp, filename, pos, angle, scale, rotation);
	obj->partsUsed++;
	
	printf("..Done!\n\n");
}

/** 
 * allocateStaticObject
 * @param StaticObject *obj = The staticObject where the mesh should be allocated
 */
void allocateStaticObject(StaticObject *obj) {
	obj->mesh = (ObjectMesh*)malloc(sizeof(ObjectMesh));
}

/** 
 * initStaticObject
 * @param StaticObject *obj = The staticObject that should be initiated
 * @param char filename[] = the obj filename
 * @param Location pos = the position in world coordinates
 * @param float angle = the angle in the world coordinates
 */
void initStaticObject(StaticObject *obj, char filename[100], Location pos, float angle, float scale, XYZ rotation) {
	(*obj).pos = pos;
	(*obj).angle.x = 0.0f;
	(*obj).angle.y = 0.0f;
	(*obj).angle.z = angle;
	initObjectMesh(obj->mesh, filename, scale,rotation);
}

/**
 * void spawnPlayer respawns the player
 */
void spawnPlayer(PlayerObject *player) {
	player->angle.x = 0.0f;
	player->angle.y = 0.0f;
	player->angle.z = 0.0f;	
	
	player->velocity.x = 0.0f;
	player->velocity.y = 0.0f;
	player->velocity.z = 0.0f;
	
	player->directionalVelocity = 0.0;
	
	player->life = 100;
	
	player->isDead = 0;
	player->effect = 0;
	player->effect_timer = 0.0;
	
	player->weapon = WEAPON_NONE;
	player->ammo = 0;
	
	int n;
	n=rand() % 5;
	switch (n) {
		case 0:
			player->pos.x= 20.0f;
			player->pos.y= 20.0f;
			player->pos.z= 0.0f;
			break;
		case 1:
			player->pos.x= -20.0f;
			player->pos.y= -20.0f;
			player->pos.z= 0.0f;
			break;
		case 2:
			player->pos.x= -20.0f;
			player->pos.y= 20.0f;
			player->pos.z= 0.0f;
			break;
		case 3:
			player->pos.x= 20.0f;
			player->pos.y= -20.0f;
			player->pos.z= 0.0f;
			break;
		case 4:
			player->pos.x= 50.0f;
			player->pos.y= 20.0f;
			player->pos.z= 0.0f;
			break;
		default:
			player->pos.x= 0.0f;
			player->pos.y= 0.0f;
			player->pos.z= 0.0f;
			break;
	}
}

void playerKilled(PlayerObject *killer, PlayerObject *pray, int killAnimation) {
	char msg[30];
	sprintf(msg, "%s pwned %s", killer->identifier, pray->identifier);
	textMessageAdd(msg);
	pray->effect = killAnimation;
	pray->death++;
	killer->score++;
}

void gameReset(PlayerObject *player1, PlayerObject *player2) {
	(*player1).score = 0;
	(*player1).death = 0;
	(*player1).life = 100;
	(*player1).isDead = 1;
	(*player1).weapon = 0;
	(*player1).ammo = 0;
	(*player1).lastShootTime = 0.0;
	(*player1).velocity.x = 0;	
	(*player1).velocity.y = 0;	
	(*player1).velocity.z = 0;
	(*player1).directionalVelocity = 0;
	(*player1).effect = 0;
	(*player1).effect_timer = 0.0;
	(*player1).cameraAngle = 0.0;
	
	(*player2).score = 0;
	(*player2).death = 0;
	(*player2).life = 100;
	(*player2).isDead = 1;
	(*player2).weapon = 0;
	(*player2).ammo = 0;
	(*player2).lastShootTime = 0.0;
	(*player2).velocity.x = 0;	
	(*player2).velocity.y = 0;	
	(*player2).velocity.z = 0;
	(*player2).directionalVelocity = 0;
	(*player2).effect = 0;
	(*player2).effect_timer = 0.0;
	(*player2).cameraAngle = 0.0;
	
	// remove bullets
	int i = 0;
	while (i<BULLET_ARRAY_MAX) {
		if (bulletArray[i] != 0) {
			removeBullet(bulletArray[i]);
		}
		i++;
	}
	i = 0;
	while (i<COLLISIONOBJECT_ARRAY_MAX) {
		if (collisionObjectArray[i] != 0) {
			removeCollisionObject(collisionObjectArray[i]);
		}
		i++;
	}
	/*
	i = 0;
	while (i<MODEL_ARRAY_MAX) {
		if (modelArray[i] != 0) {
			removeModel(modelArray[i]);
		}
		i++;
	}
	*/
	
	objectPopulation();
}
